package EMM;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Vector;

public class SearchDeviceImpl implements SearchDevice {
		
	private String 			_groupStr		= 	"224.0.0.1";
	private	MulticastSocket _sockMultiC 	= 	null;
	private int				_defaultPort	=	2002;
	
	private ResponseThread	_responseThread	=	null;
	private boolean			_quit			=	false;
	private Vector			_deviceList		=	new Vector();
	
	public void run() throws IOException {
		try {
					_responseThread	=	new ResponseThread();
					
					_responseThread.setDaemon(true);
					this.SetGroup();
					
					_responseThread.start();
			
		}
		catch (IOException e )
		{
			System.err.println( e.toString() );
		}
		
		
	}
	
	public Vector	getDeviceList()	{
		return _deviceList;
	}
	
	public int		getDeviceCount()	{
		return _deviceList.size();
	}

	public boolean searchDevice(String ipAddr) throws IOException, InterruptedException {
		String 	groupIpAddr 	= 	ipAddr;
		try {
			MulticastSocket	mulSock	=	new MulticastSocket();
			int ttl = mulSock.getTimeToLive();  
			byte buf[] = new byte[10];
			for (int i=0; i<buf.length; i++) 
				buf[i] = (byte)i;
			 
			DatagramPacket pack = new DatagramPacket(buf, buf.length, InetAddress.getByName(groupIpAddr), 2002 );
			
			mulSock.setTimeToLive(ttl);
			
			mulSock.send(pack);
			
			int a = 1;
			try {
				while( a > 0 ) {
					a--;
					Thread.sleep(100);
					mulSock.receive(pack);
					String	tempStr;
							tempStr		=	pack.getAddress().toString();
								
					_deviceList.addElement( tempStr );
				}
			} catch( InterruptedException e)
			{
				System.err.println( e.toString() );
			}
			
		
			mulSock.close();
			return true;
		} 
		catch( IOException e ) 
		{
			System.err.println( e.toString() );
			return false;
		}
	}

	public void SetGroup( String group ) throws UnknownHostException, IOException 
	{
		try {
			if( _sockMultiC != null )
				_sockMultiC.joinGroup(InetAddress.getByName(group));
			
			return ;
		}
		catch( UnknownHostException e) {
			System.err.println( e.toString() );
			return ;
		}
		catch( IOException e ) {
			System.err.println( e.toString() );
			return ;
		}
		
	}
	
	public void SetGroup() throws UnknownHostException, IOException
	{
		try {
			if( _sockMultiC != null )
				_sockMultiC.joinGroup(InetAddress.getByName(_groupStr));
			
			return ;
		} catch( UnknownHostException e) {
			System.err.println( e.toString() );
			return ;
		}
	}
	
	class ResponseThread extends Thread {
			ResponseThread(){
 			super( new ThreadGroup("ResponseThreadGroup"), "ResponseThreadGroup");
		}
		
		public void run() {
			try {
				_sockMultiC	=	new MulticastSocket( _defaultPort );
				while( !_quit ) {
					byte buf[] 	= 	new byte[1024];
	
					DatagramPacket pack = new DatagramPacket(buf, buf.length);
					_sockMultiC.receive(pack);
				
					String strValid	=	ValidatePacket( pack );
					if(  strValid != null )
					{
						_sockMultiC.send(pack);
						//Socket reflectSock	=	new Socket( pack.getAddress().toString() , pack.getPort() );
						String	tempStr;
								tempStr		=	pack.getAddress().toString();
								tempStr		+=	"|" + pack.getPort();
								tempStr		+=	"|" ;
						strValid			=	tempStr + strValid;
						strValid			+= "|";
						//_deviceList.addElement( strValid );	
						//_deviceList.addElement("Testst");
					}				
				}
				
			} catch( IOException e ) {
				System.err.println( e.toString() );
			}
			
		}
		
		public String ValidatePacket( DatagramPacket packet )
		{			
			byte	compareValue[]	=	new byte[1024];
			byte	returnValue[]	=	new byte[1024];
			
			compareValue	=	packet.getData();	
			for ( int i = 0; i < packet.getLength() ; i++ )
			{
				if( i < 10 && compareValue[i] != i )
					return null;
				
				if( i >= 10 )
					returnValue[i-10] = compareValue[i];
			}
			
			return returnValue.toString();				
		}
		
	}
}
